from rsa.util.robot_utilities import get_full_name
from rsa.util.common_utilities import format_severity

class Formatter(object):
    
    def format_element(self, element, property):
        """
        Format a given element template into a understandable representation
        """
        if(not property): return ""
        if(isinstance(element, list)):
            elements = dict()
            for i in range(len(element)):
                elements["item" + str(i + 1)] = element[i]
            return property.safe_substitute(elements)
        return property.safe_substitute(item=element)
    
    def format_line(self, line):
        """
        Returns a string representation of a line. If line is None returns 0
        """
        if(line): return str(line)
        else: return "0"
    
    def format(self, violation):
        """
        Format a given violation into a specific format
        """
        rulename = violation.rule.name
        testname = get_full_name(violation.test)
        line = self.format_line(violation.line)
        message = self.format_element(violation.element, violation.rule.message)
        solution = self.format_element(violation.element, violation.rule.solution)
        severity = format_severity(violation.rule.severity)
        return self.output_representation(rulename, testname, line, severity, message, solution)
    
    def output_representation(self, rulename, testname, line, severity, message, solution):
        """
        Format the violation according to a specified format
        """
        raise NotImplementedError("Should have implemented this")


class TextFormatter(Formatter):
    """
    Format a given violation into string with the following format 
    [Severity]: [Rule] TestCase[line]: violation message | solution
    """
    
    def output_representation(self, rulename, testname, line, severity, message, solution):
        if(line == "0"): 
            return "[" + severity + "]: " + "[" + rulename + "] " + testname + ": " + message + " | " + solution 
        else: 
            return "[" + severity + "]: " + "[" + rulename + "] " + testname + "[" + line + "]" + ": " + message + " | " + solution
   
class CsvFormatter(Formatter):
    """
    Format a given violation into a comma separated value representation
    """
    
    def remove_quotes(self, str):
        """
        If exists, remove initial quotes
        """
        qoutes = ['\"', '\'']
        if((str[0] in qoutes) and (str[-1] in qoutes)):
            return str[1:-1]
        return str
    
    def output_representation(self, rulename, testname, line, severity, message, solution):
        message = self.remove_quotes(message)
        solution = self.remove_quotes(solution)
        return '"%s", "%s", "%s", "%s", "%s", "%s"' %  (severity, rulename, testname, line, message, solution)
    
class ListFormatter(Formatter):
    """
    Format a given violation into a list representation
    """   
    
    def output_representation(self, rulename, testname, line, severity, message, solution):
        return [severity, message, solution, testname, line, rulename]

class HTMLFormatter(Formatter):
    """
    Format a given violation into string with the following format 
    severity&testname&line&rulename&message&solution
    """
    
    def output_representation(self, rulename, testname, line, severity, message, solution):
        if(line == "0"): 
            return testname + "&" + severity + "&" + "-" + "&" + rulename + "&" + message + "&" + solution 
        else: 
            return testname + "&" + severity + "&" + line + "&" + rulename + "&" + message + "&" + solution

class FormatterFactory(object):
    """
    This class deals with the problem of creating output Formatters specifying 
    the class of object that will be created
    """
    csv = "csv"
    text = "text"
    html = "html"
    list = "list"
    
    def get_formatter(self, format=None):
        """
        Returns a specific instance of Formatter, if the argument format is not
        specified return the default formatter (TextFormatter)
        """
        if(not format or self.text in format): 
            return TextFormatter()
        elif(self.csv in format):
            return CsvFormatter()
        elif (self.html in format):
            return HTMLFormatter()
        elif (self.list in format):
            return ListFormatter()
        else:
            return TextFormatter()
